zlib1.dll and conflicts

Certain Haskell libraries depend on C library GTK+ or its dependencies (such as Cairo or Pango). The dependencies include zlib, a compression library. On Windows, these libraries can be obtained most easily using MSYS2.

The DLL build of zlib is named zlib1.dll. zlib has developed over time and later versions of zlib1.dll export functions that are not available in earlier versions.

In particular, at the time of writing, the version of GHC installed by the Haskell Tool Stack (stack) includes version 1.2.8 of zlib released in April 2003. The version provided by MSYS2 is 1.2.11 released in January 2017.

zlib1.dll conflicts

Unfortunately, the stack environment prefixes the path to its version of zlib1.dll to the PATH environment variable.

Other applications may also put superseded versions of zlib1.dll on the PATH ahead of the version provided by MSYS2. This will give rise to obscure errors when building Haskell projects that depend on GTK+ or its dependencies.

The solution is to replace each out-of-date zlib1.dll with the up-to-date version provided by MSYS2.

Visual Studio’s dumpbin

Visual Studio provides a tool dumpbin which allows you to inspect a DLL. In Visual Studio Community 2017 it is found at C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\bin\Hostx86\x86. The Visual Studio Developer Command Prompt adds this location to the PATH.

zlibVersion

Versions of zlib from 1.0.2 (released in May 1996) export a function zlibVersion with the function declaration (in zlib.h):

Haskell’s Foreign Function Interface (enabled by default in GHC) allows the following use of that function:

In order for stack build to work, the package.yaml must identify the extra library "zlib1" and where it is located. In this example, a copy of zlib1.dll has been placed in a lib folder, identified using extra-lib-dirs. The extract from package.yaml is shown below.

The corresponding extract from the zlibVersion.cabal file is as follows:

If the resulting executable is run in the folder containing a zlib1.dll file, it reports the version of that DLL.